
#include "../include/tsmp_api.h"


//raw socket句柄变量定义
int sock_raw_fd =-1;
struct sockaddr_ll sll;

u8 *recv_buf = NULL;


int do_promisc(int f,unsigned char* net_interface) 
{
    int s;
    struct ifreq ifr;
    strcpy(ifr.ifr_name, net_interface);
    //strncpy(ifr.ifr_name,net_interface, IFNAMSIZ);

#if 1    
    if ((s = ioctl(f, SIOCGIFFLAGS, &ifr))<0)
	{
      close(f);
      return-1;
    }
    
    if(ifr.ifr_flags & IFF_RUNNING)
	{
        CNCAPI_DBG("eth link up\n");
    }else{
        CNCAPI_DBG("eth link down\n");
		return -1;
    }
 
    ifr.ifr_flags |= IFF_PROMISC;
    if ((s = ioctl(f, SIOCSIFFLAGS, &ifr)) < 0)
	{
		CNCAPI_DBG("promisc fail\n");
       return -1;
    }
#endif
	
    CNCAPI_DBG("Setting interface ::: %s ::: to promisc\n\n", ifr.ifr_name);

	return 0;
}

int set_data_filter(struct sock_fprog filter)
{

	if (setsockopt(sock_raw_fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0) {
        perror("setsockopt fail\n"); 
        return -1;   
    }
	
	return 0;
}

int create_socket_handle(unsigned char* net_interface)
{
	int fd;
	int ret = 0;
	//原始套接字地址结构
	struct ifreq req;	
	 	
	//获取网络接口名字
	CNCAPI_DBG("net_interface:%s\n",net_interface);
	if(NULL == net_interface)
	{
	    perror("pcap_lookupdev");
	    return -1;	
	}

	fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (fd < 0 ) {
        perror("socket fail\n");
        return -1;
    }

	//指定网卡名称
	//strcpy(req.ifr_name, net_interface);
	strncpy(req.ifr_name,net_interface, IFNAMSIZ);		   
	
	if(-1 == ioctl(fd, SIOCGIFINDEX, &req))
	{
		printf("ioctl error!\n");
		close(fd);
		return -1;
	}

	/*将网络接口赋值给原始套接字地址结构*/
	bzero(&sll, sizeof(sll));
	sll.sll_ifindex = req.ifr_ifindex;

#if 1
	//开启混杂模式
	ret = do_promisc(fd,net_interface);
	if (ret < 0 ) {
        perror("do_promisc fail\n");
		close(fd);
        return -1;
    }
#endif

	sock_raw_fd = fd;
	return 0;	
}

int tsmp_pkt_send_recv_init(u8* net_interface,struct sock_fprog filter)
{	
	int ret = 0;
	
	//获取网络接口名字
	CNCAPI_DBG("net_interface:%s\n",net_interface);
	if(NULL == net_interface)
	{
	    perror("net_interface is NULL");
	    return -1;	
	}

	recv_buf = (u8 *)malloc(MAX_PKT_LEN);
	if(NULL == recv_buf)
	{
		printf("tsmp_pkt_send_recv_init,malloc buf fail\n");
		return -1;
	}
	
	bzero(recv_buf,MAX_PKT_LEN);

	ret = create_socket_handle(net_interface);
	if(ret == -1)
	{
		printf("create_socket_handle fail\n");

		free(recv_buf);
		return -1;
	}

	/*配置过滤器*/
#if 1
	ret = set_data_filter(filter);
	if(ret == -1)
	{
		printf("set_data_filter fail\n");
		free(recv_buf);
		return -1;
	}

#endif
	return 0;	
}


/*
	定义：int data_pkt_send_handle(u8* pkt,u16 len);
	功能：完成数据报文的发送处理
	输入参数：数据报文指针、数据报文长度
	返回结果：成功返回0，失败返回-1
*/

int tsmp_pkt_send_handle(u8* pkt,u16 len)
{

	int strlen;

	//printf("send pkt\n");
	cnc_pkt_print(pkt,len);

	strlen = sendto(sock_raw_fd, pkt, len, 0 , (struct sockaddr *)&sll, sizeof(sll));
	if(len == -1)
	{
	   CNCAPI_ERR("sendto fail\n");
	   return -1;
	}
	
	return 0;
}

u8 *tsmp_pkt_receive_dispatch_1(u16 *len)
{
	int pkt_len = 0;
	
	pkt_len = recv(sock_raw_fd, recv_buf, MAX_PKT_LEN, MSG_DONTWAIT);
	
	if(pkt_len < 0)//未捕获数据包
	{
	    len = 0;
		return NULL;
	}
	else
	{
		//printf("get pkt\n");
		cnc_pkt_print(recv_buf,pkt_len);
		*len = pkt_len;		
		return recv_buf;
	}

	return recv_buf;
	
}


int tsmp_pkt_send_recv_destroy()
{
	close(sock_raw_fd);
	free(recv_buf);
	return 0;
}



